<?php


App::import('Model', 'WorkflowWorkflow');
App::import('Vendor', 'CakeWorkflowExecution');
class PedidosController extends AppController {
    var $name="Pedido";
    var $helpers=array('Html','Form');

    function index(){
        
    }

    function nuevo(){
         if(!empty($this->data)){
            if($this->Pedido->save($this->data)){
                $finalizado=$this->_ejecutarWF($this->Pedido->id, $this->data['Pedido']['monto']);
                if($finalizado){
                    $this->Session->setFlash('El pedido se guardó correctamente.');
                }else{
                    $this->Session->setFlash('El pedido quedó en estado pendiente de aprobación.');
                }
                $this->redirect(array('action' => 'index'));
            }
        }
    }

    function _updatePedido($id,$state){
        /*Se supone que deberia heredar esta propiedad, pero no lo hace*/
        $this->Pedido=ClassRegistry::init('Pedido');
        $this->Pedido->read(null, $id);
        $this->Pedido->set('aceptado',$state);
        $this->Pedido->save();
        //unset($this->Pedido);
        ClassRegistry::flush();
    }

    function _ejecutarWF($idPedido,$monto){
        //carga el wf
        $wf=$this->_loadWF();
        //ejecuta el wf
        $execution = new CakeWorkflowExecution();
        $execution->workflow = $wf;
        $montoAlto=(bool)($monto>100000);
        $execution->start();
        $execution->resume(array('idPedido' => (int)$idPedido));
        $execution->resume(array('montoAlto' => $montoAlto));
        if(!$execution->hasEnded()){
            return false;
        }
        return true;
    }

    function _loadWF(){
        $this->Definition = ClassRegistry::init('WorkflowWorkflow');
        $existe = $this->Definition->existsByName('PedidoWF');
        if(!$existe){
            //la definicion del wf no existe en bd, hay que guardarla
            $workflow = new ezcWorkflow( 'PedidoWF' );
            $idNode = new ezcWorkflowNodeInput(array( 'idPedido' => new ezcWorkflowConditionIsInteger()));
            $input = new ezcWorkflowNodeInput(array( 'montoAlto' => new ezcWorkflowConditionIsBool));
            $workflow->startNode->addOutNode( $idNode );
            $idNode->addOutNode($input);
            $branch = new ezcWorkflowNodeExclusiveChoice;
            $branch->addInNode( $input );
            $trueNode = new ezcWorkflowNodeAction( array( 'class' => 'PedidosAltosController'));
            $falseNode = new ezcWorkflowNodeAction( array( 'class' => 'PedidosBajosController'));

            $branch->addConditionalOutNode(
                    new ezcWorkflowConditionVariable( 'montoAlto', new ezcWorkflowConditionIsTrue ),
                    $trueNode );
            $branch->addConditionalOutNode(
                    new ezcWorkflowConditionVariable( 'montoAlto', new ezcWorkflowConditionIsFalse ),
                    $falseNode
            );

            $inputAutoriza = new ezcWorkflowNodeInput(
                    array( 'autoriza' => new ezcWorkflowConditionIsBool )
            );

            $inputAutoriza->addInNode($trueNode);

            $branchAutoriza = new ezcWorkflowNodeExclusiveChoice;
            $branchAutoriza->addInNode( $inputAutoriza );

            $autorizaNode = new ezcWorkflowNodeAction( array( 'class' => 'PedidosAutorizadoController'));
            $noAutorizaNode = new ezcWorkflowNodeAction( array( 'class' => 'PedidosNoAutorizadoController'));

            $branchAutoriza->addConditionalOutNode(
                    new ezcWorkflowConditionVariable( 'autoriza', new ezcWorkflowConditionIsTrue ),
                    $autorizaNode );
            $branchAutoriza->addConditionalOutNode(
                    new ezcWorkflowConditionVariable( 'autoriza', new ezcWorkflowConditionIsFalse ),
                    $noAutorizaNode );

            $merge = new ezcWorkflowNodeSimpleMerge;
            //$merge->addInNode( $trueNode );
            $merge->addInNode($autorizaNode);
            $merge->addInNode($noAutorizaNode);
            $merge->addInNode( $falseNode );
            $merge->addOutNode( $workflow->endNode );
            $this->Definition->save($workflow);
        }else{
            //carga la definicion de base de datos
            $workflow = $this->Definition->loadByName('PedidoWF');
        }
        unset($this->Definition);
        ClassRegistry::flush();
        return $workflow;
    }

    function listar(){
        $this->set('pedidos',$this->Pedido->find('all'));
    }

    function listarEstado($estado){
        $this->set('pedidos',$this->Pedido->find('all',array('conditions'=>array('Pedido.aceptado'=>$estado))));
    }
    
    function listaWF(){
        $this->set('wfs', $this->_idWF());

    }

    function _idWF(){
        $wf=$this->_loadWF();
        $this->WorkflowExecution = ClassRegistry::init('WorkflowExecution');
        $exs=$this->WorkflowExecution->find('all');
        $data=array();
        for ($i=0;$i<count($exs);$i++){
            $idwfe=(int)$exs[$i]['WorkflowExecution']['id'];
            $data[$i]['id']=$idwfe;
            $execution = new CakeWorkflowExecution($idwfe);
            $execution->workflow = $wf;
            $idP=(int)$execution->getVariable('idPedido');
            $data[$i]['pedido']=$idP;
            $this->Pedido->read(null,$idP);
            $data[$i]['medico']=$this->Pedido->data['Pedido']['medico'];
            $data[$i]['paciente']=$this->Pedido->data['Pedido']['paciente'];
            $data[$i]['monto']=$this->Pedido->data['Pedido']['monto'];
        }
        unset($this->WorkflowExecution);
        ClassRegistry::flush();
        return $data;
    }

    function continuarWF($idWfE,$autoriza){
        //carga el wf
        $wf=$this->_loadWF();
        $execution = new CakeWorkflowExecution((int)$idWfE);
        $execution->workflow = $wf;
        $execution->resume(array('autoriza' => (bool)$autoriza));
        $this->Session->setFlash('El pedido ha sido actualizado.');
        $this->redirect(array('action' => 'listaWF'));
    }

}


class PedidosAltosController extends PedidosController implements ezcWorkflowServiceObject {

    public function __toString() {
        return 'PedidosAltosController';
    }

    public function execute(ezcWorkflowExecution $execution) {
        $execution->setVariable( 'montoAlto', true );
        $this->_updatePedido($execution->getVariable('idPedido'),2);
        return true;
    }

}

class PedidosBajosController extends PedidosController implements ezcWorkflowServiceObject {

    public function __toString() {
        return 'PedidosBajosController';
    }

    public function execute(ezcWorkflowExecution $execution) {
        $execution->setVariable( 'montoAlto', false );
        $this->_updatePedido($execution->getVariable('idPedido'),1);
        return true;
    }

}
class PedidosAutorizadoController extends PedidosController implements ezcWorkflowServiceObject {

    public function __toString() {
        return 'PedidosAutorizadoController';
    }

    public function execute(ezcWorkflowExecution $execution) {
        $execution->setVariable( 'autoriza', true );
        $this->_updatePedido($execution->getVariable('idPedido'),1);
        return true;
    }

}
class PedidosNoAutorizadoController extends PedidosController implements ezcWorkflowServiceObject {

    public function __toString() {
        return 'PedidosNoAutorizadoController';
    }

    public function execute(ezcWorkflowExecution $execution) {
        $execution->setVariable( 'autoriza', false );
        $this->_updatePedido($execution->getVariable('idPedido'),3);
        return true;
    }

}
?>
